package com.miyake.loveviewweb.client.viewer;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public abstract class AbstractListWidget<T> extends Composite {
    protected Widget getHeader() {return new HTML("");};
    protected Widget getFooter() {return new HTML("");};
    
    public Grid getGrid() {
        return grid;
    }

    public void setGrid(Grid grid) {
        this.grid = grid;
    }

    public AbstractListWidget() {
        VerticalPanel panel = new VerticalPanel();
        panel.add(getHeader());
        panel.setWidth("100%");
        panel.add(grid);
        panel.add(getFooter());
        initWidget(panel);
        grid.setSize("100%", "100%");
    }
    
    public List<T> getElements() {
        return elements;
    }

    public void setElements(List<T> elements) {
        this.elements = elements;
    }

    public Integer getColumns() {
        return columns;
    }

    public void setColumns(Integer columns) {
        this.columns = columns;
        resize();
    }

    private Grid grid = new Grid();
    private Integer columns = 2;
    private List<T> elements = new ArrayList<T>();
    
    private void resize() {
        List<Widget> widgets = new ArrayList<Widget>();
        for (int row = 0; row < grid.getRowCount(); row++) {
            for (int column = 0; column < grid.getColumnCount(); column++) {
                widgets.add(grid.getWidget(row, column));
            }
        }
        int rows = elements.size() / this.columns+1;
        if (rows == 0) {
            rows = 1;
        }
        grid.resize(rows, columns);
        Iterator<Widget> it = widgets.iterator();
        for (int row = 0; row < grid.getRowCount(); row++) {
            for (int column = 0; column < grid.getColumnCount(); column++) {
                if (it.hasNext()) {
                    grid.setWidget(row, column, it.next());
                }
                else {
                    return;
                }
            }
        }
    }
    
    public void update() {
        int rows = elements.size() / this.columns+1;
        if (rows == 0) {
            rows = 1;
        }
        grid.resize(rows, columns);
        Iterator<T> it = elements.iterator();
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < columns; col++) {
                if (it.hasNext()) {
                    Widget widget = getWidget(it.next());
                    grid.setWidget(row, col, widget);                   
                }
            }
        }
    }

    protected abstract Widget getWidget(T element);
    
    public void replace(T oldObject, T newObject) {
        int index = elements.indexOf(oldObject);
        elements.remove(oldObject);
        elements.add(index, newObject);
        
        int row = index / grid.getColumnCount();
        int col = index % grid.getColumnCount();
        grid.setWidget(row, col, getWidget(newObject));
    }
}
